
#include "BondMacroIndex.h"

#include <algorithm>

#include "../time/date.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// class CBondMacroIndex

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
static void Int2String(unsigned int input, std::string& str) {
  char buf[256] = {0};
  buf[0] = '\0';
  FMTBUF(buf, "%d", input);
  str = buf;
}

CBondMacroIndex::CBondMacroIndex() {}

CBondMacroIndex::~CBondMacroIndex() { Clear(); }

CBondMacroIndex& CBondMacroIndex::instance() {
  static CBondMacroIndex s_instance;
  return s_instance;
}

bool CBondMacroIndex::Clear() {
  // CBondMacroData	data;
  // m_macro_data.m_data.clear();
  // m_macro_data.m_data.swap(data.m_data);

  m_macro_data.m_values.clear();
  return true;
}

int GetCalendarDate(int ndate) {
  int idate = 0;
  struct tm tt;
  memset(&tt, 0, sizeof(tm));
  tt.tm_year = ndate / 10000 - 1900;
  tt.tm_mon = (ndate / 100) % 100 - 1;
  tt.tm_mday = ndate % 100;
  tt.tm_hour = 8;
  time_t t = mktime(&tt);
  idate = qb::base::IntDate::timeToInt(t);
  return idate;
}

void CBondMacroIndex::Add(const char* code, const Macro_Index_Value& element) {
  // m_macro_data.m_data.push_back( element);

  CodeMacroListMap::iterator iter = m_macro_data.m_values.find(code);
  if (iter != m_macro_data.m_values.end()) {
    MacroValueList& vec = iter->second;
    vec.push_back(element);
  } else {
    m_macro_data.m_values.insert(make_pair(code, MacroValueList(1, element)));
  }
}
bool CBondMacroIndex::Load(ILoader* loader) {
  std::lock_guard<std::mutex> l(m_mutex);
  Clear();
  loader->LoadMacroIndex(this);
  SortMacroIndex();
  return true;
}

int CBondMacroIndex::GetSize() {
  int res = 0;
  for (CodeMacroListMap::const_iterator iter = m_macro_data.m_values.begin();
       iter != m_macro_data.m_values.end(); ++iter) {
    res += (int)iter->second.size();
  }
  return res;
}

double CBondMacroIndex::GetMaxDateByCod(const char* pCode) {
  int nBeginDate = -1;
  double dvalue = -1.0;

  CodeMacroListMap::iterator itFind = m_macro_data.m_values.find(pCode);
  if (itFind != m_macro_data.m_values.end()) {
    MacroValueList& vec = itFind->second;
    if (!vec.empty()) {
      MacroValueList::iterator iter = vec.end() - 1;
      if (iter != vec.end()) {
        dvalue = iter->fvalue;
      }
    }
  }

  return dvalue;
}

CBondMacroData& CBondMacroIndex::GetBondMacro() { return m_macro_data; }

void CBondMacroIndex::SortMacroIndex() {
  for (CodeMacroListMap::iterator iter = m_macro_data.m_values.begin();
       iter != m_macro_data.m_values.end(); ++iter) {
    MacroValueList& vec = iter->second;
    std::sort(vec.begin(), vec.end(), Macro_Comp());
  }
}

int CBondMacroIndex::GetAllData(
    std::vector<ssCalculator::SSSingleInterestRate>& rates, int capcity) {
  if (capcity <= 0) return 0;
  int nadded = 0;
  std::lock_guard<std::mutex> l(m_mutex);

  CBondMacroData& info = m_macro_data;
  for (CodeMacroListMap::const_iterator iter = info.m_values.begin();
       nadded < capcity && iter != info.m_values.end(); ++iter) {
    const MacroValueList& vec = iter->second;
    std::string code = iter->first;
    for (MacroValueList::const_iterator it = vec.begin();
         nadded < capcity && it != vec.end(); ++it) {
      ssCalculator::SSSingleInterestRate data;
      data.index_id_ = code;
      Int2String(it->begin_date, data.startDate_);
      Int2String(it->end_date, data.endDate_);
      data.value_ = it->fvalue / 100;
      if (data.value_ == 999999999999999.0) continue;
      rates.push_back(data);
      nadded++;
      if (nadded >= capcity) return nadded;
    }
  }
  return nadded;
}
